package service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jetty.util.component.Container;

import entity.ContainerStats;
import entity.MasterConfig;
import entity.ServerDockerContainterProcess;
import utils.DockerManager;

public class DSTServerDockerService {
    private MasterConfig config;
    private DockerManager dockerManager;

    private final String StartGame = "screen -d -m -S \"MAIN_SCREEN\"";
    private final String ShutDown = "screen -S \"MAIN_SCREEN\" -p 0 -X stuff \"c_shutdown(true)\\n\"";

    public DSTServerDockerService(DockerManager dockerManager, MasterConfig config)
    {
        this.config = config;
        this.dockerManager = dockerManager;
    }

    public ServerDockerContainterProcess createNewServerContainer(String dockerImage, String archiveID, String shard)
    {
        return createNewServerContainerWithLimit(
            dockerImage, archiveID, shard,
            null, null, null
        );
    }

    // 配合启动脚本启动
    public ServerDockerContainterProcess createNewServerContainerWithLimit(String dockerImage, 
        String archiveID, String shard,
        Integer mem, Integer swap, Float cpupercent
    )
    {
        String id;
        Long memery;
        Long memery_swap;
        Long cpuPeriod;
        Long cpuQuota;
        if (archiveID == null || shard == null || dockerImage == null)
        {
            System.err.println("createNewServerContainer(): args is null");
            return null;
        }

        HashMap<String, String> mounts = new HashMap<>();
        String gameServerBindPath = config.getGameServerBindPath();
        String kleiBindPath = config.getKleiBindPath();

        if (gameServerBindPath == null || kleiBindPath == null)
        {
            System.err.println("read gameServerBindPath or kleiBindPath fail.");
            return null;
        }

        mounts.put(gameServerBindPath, "/root/game_server");
        mounts.put(kleiBindPath, "/root/.klei");
        ArrayList<String> cmds = new ArrayList<>();
        
        // cmds.addAll(Arrays.asList(StartGame.split(" ")));
        cmds.add("sh");
        cmds.add("/root/game_server/dont_starve/bin/start_dst.sh");
        cmds.add("11009");
        cmds.add(archiveID);
        cmds.add(shard);

        // cmds.add("-c");
        // cmds.add("\"");

        // cmds.add("nc");
        // cmds.add("-l");
        // cmds.add("-p");
        // cmds.add("11001");
        // cmds.add("|");
        // cmds.add("/root/game_server/dont_starve/bin/dontstarve_dedicated_server_nullrenderer");
        // cmds.add("-console");
        // cmds.add("-cluster");
        // cmds.add(archiveID);
        // cmds.add("-shard");
        // cmds.add(shard);

        // cmds.add("\"");
        String workDir = "/root/game_server/dont_starve/bin/";
        Map<String, String> labels = new HashMap<>();
        labels.put("shard", shard);
        if (mem == null || swap == null || cpupercent == null)
        {
            id = dockerManager.createContainer(dockerImage, mounts, null, cmds, workDir, labels);
        } else {
            memery = mem * 1024L * 1024L;
            memery_swap = swap * 1024L * 1024L;
            cpuPeriod = 100000L;
            cpuQuota = (long) Math.round(cpuPeriod * cpupercent);
            id = dockerManager.createContainerWithLimit(
                dockerImage, mounts, null, 
                memery, memery_swap, cpuPeriod, cpuQuota, 
                null, null,
                cmds, workDir, labels
            );
        }
        if (id != null)
        {
            ServerDockerContainterProcess res = new ServerDockerContainterProcess(
                archiveID, id, workDir,
                mem, swap, cpupercent
            );
            res.setTag(shard);
            return res;
        }
        return null;
    }

    public int startContainer(String containterID)
    {
        System.out.println("Started container with ID: " + containterID);
        int res = dockerManager.startContainter(containterID);
        if(res != 0)
        {
            System.err.println("container start fail: " + containterID);
        }

        return res;
    }

    public int stopContainer(String containterID)
    {
        int res = dockerManager.stopContainer(containterID);
        if(res != 0)
        {
            System.err.println("container stop fail: " + containterID);
        }

        return res;
    }

    public int delete(String containterID) {
        int res = dockerManager.deleteContainer(containterID);
        if(res != 0)
        {
            System.err.println("container delete fail: " + containterID);
        }

        return res;
    }

    public ContainerStats getStats(String containterID) {
        ContainerStats res = dockerManager.getStats(containterID);
        if(res == null)
        {
            System.err.println("container delete fail: " + containterID);
        }

        return res;
    }
}
